home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / sdk / vfw11.win / vfwdk / ctdev.c_ / ctdev.bin
Encoding:
Text File  |  1993-11-19  |  14.3 KB  |  573 lines

  1. /****************************************************************************
  2.  *
  3.  *   ctdev.c
  4.  * 
  5.  *   Hardware specific routines.  
  6.  *
  7.  *   Microsoft Video for Windows Sample Capture Driver
  8.  *   Chips & Technologies 9001 based frame grabbers.
  9.  *
  10.  ***************************************************************************/
  11. /**************************************************************************
  12.  *
  13.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  14.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  15.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  16.  *  PURPOSE.
  17.  *
  18.  *  Copyright (c) 1992, 1993  Microsoft Corporation.  All Rights Reserved.
  19.  * 
  20.  **************************************************************************/
  21.  
  22. #include <windows.h>
  23. #include <mmsystem.h>
  24. #include <conio.h>
  25. #include <msvideo.h>
  26. #include <msviddrv.h>
  27. #include "ct.h"         // General include
  28. #include "ctdev.h"      // Device specific include
  29. #include "debug.h"      
  30.  
  31. #ifdef _VBLASTER
  32. #include "pcvideo.h"
  33. char gszDriverName[]              = "VBlaster.drv";
  34. #endif
  35.  
  36. #ifdef _BRAVADO
  37. #include "vwproto.h"
  38. VWCFG VWConfigBuf;
  39. char gszDriverName[]              = "Bravado.drv";
  40. #endif
  41.  
  42. #define KEY_COLOR_INDEX  5
  43.  
  44. WORD FAR PASCAL GetProfileHex(LPSTR szApp, LPSTR szEntry, WORD wDef);
  45.  
  46. static HBRUSH   hOverlayBrush;      // Overlay brush used to paint window
  47. static RECT     rcLastScreen;       // Last screen coords of overlay window
  48. static BOOL     fOverlayEnabled;    // Is overlay showing?
  49.  
  50. /*======================================================== 
  51.              Low level read/write routines               
  52. =========================================================*/
  53.  
  54. // Write a byte to a PCVideo Chip register
  55. void FAR PASCAL CT_WritePCVideo (int nIndex, int nValue)
  56. {
  57.     outp (wPCVideoAddress, nIndex);
  58.     outp (wPCVideoAddress + 1, nValue);
  59. }
  60.  
  61. // Read a byte from a PC Video chip register
  62. int FAR PASCAL CT_ReadPCVideo (int nIndex)
  63. {
  64.     outp (wPCVideoAddress, nIndex);
  65.     return (inp (wPCVideoAddress + 1));
  66. }
  67.  
  68.  
  69. /*======================================================== 
  70.              Initialization and Fini
  71. =========================================================*/
  72.  
  73. // Initialization routine called only once at driver load time.
  74. // Returns TRUE on success
  75. BOOL FAR PASCAL CT_Init ()
  76. {
  77.     WORD wRet;
  78.     WORD wLuma;
  79.  
  80. #pragma message("Try reducing luma bandwidth!!!")
  81.     wLuma = GetProfileHex(gszDriverName, "9051Reg6", 0x6c );
  82.  
  83. #ifdef _BRAVADO
  84.     VW_SetConfigBuf (&VWConfigBuf);
  85.     VW_SetDefaultConfiguration (0);
  86.     CT_SetPortAddress (wPCVideoAddress); 
  87.  
  88.     wRet = (VW_Init (0) == 1);  // returns 1 on success
  89.     VW_Set9051Reg (6, wLuma);    // Lower luma bandwidth to reduce noise!!!
  90. #endif
  91.  
  92. #ifdef _VBLASTER
  93.     wRet = vbcInitialize (); 
  94.     vbcSetRegister (0x8a06, (BYTE) wLuma);
  95. #endif
  96.  
  97.     if (wRet) {
  98.         wPCVideoAddress = CT_GetPortAddress ();
  99.  
  100.         // Create the overlay brush
  101.         hOverlayBrush = CT_SetKeyColor ();
  102.         CT_OverlayEnable (FALSE);   // Initially disable the overlay
  103.         CT_Acquire (FALSE);         // Turn off acquisition so we can test memory
  104.     }
  105.     return wRet;
  106. }
  107.  
  108. // Called during shutdown of the driver.
  109. void FAR PASCAL CT_Fini ()
  110. {
  111.     if (hOverlayBrush) {
  112.         DeleteObject (hOverlayBrush);
  113.         hOverlayBrush = NULL;
  114.     }
  115.  
  116. #ifdef _BRAVADO
  117.     VW_CleanUp ();
  118. #endif
  119.  
  120. #ifdef _VBLASTER
  121.     vbcExit (); 
  122. #endif
  123. }
  124.  
  125. /*======================================================== 
  126.                 Ports and addresses
  127. =========================================================*/
  128.  
  129. // Set the Base I/O port used by the device
  130. void FAR PASCAL CT_SetPortAddress (int nPort)
  131. {
  132. #ifdef _BRAVADO
  133.     VW_SetIOAddr (nPort);
  134. #endif
  135.  
  136. #ifdef _VBLASTER
  137.     PCV_SetPortAddress (nPort);   // This doesn't work!!!
  138. #endif
  139.  
  140.     wPCVideoAddress = CT_GetPortAddress ();
  141. }
  142.  
  143. // Get the Base I/O port used by the device
  144. int FAR PASCAL CT_GetPortAddress ()
  145. {
  146. #ifdef _BRAVADO
  147.     return VW_GetIOAddr ();
  148. #endif
  149.  
  150. #ifdef _VBLASTER
  151.     // VBlaster uses the address set in the Creative Labs setup app.
  152.     return vbcGetPortAddress ();
  153. #endif
  154. }
  155.  
  156. // Get Linear memory address of frame buffer
  157. // Returns value in the range 1 to 15 (meg)
  158. int FAR PASCAL CT_GetFrameAddress ()
  159. {
  160. #ifdef _BRAVADO
  161.     return VW_GetVidAddr ();
  162. #endif
  163.  
  164. #ifdef _VBLASTER
  165.     return vbcGetVideoAddress ();
  166. #endif
  167. }
  168.  
  169. // Set Linear memory address of frame buffer
  170. // nVidAddr is linear address div. 0x100000 (ie. 1-15)
  171. int FAR PASCAL CT_SetFrameAddress (int nVidAddr)
  172. {
  173. #ifdef _BRAVADO
  174.     return VW_SetVidAddr (nVidAddr);
  175. #endif
  176.  
  177. #ifdef _VBLASTER
  178.     return vbcSetVideoAddress (nVidAddr);
  179. #endif
  180. }
  181.  
  182. /*======================================================== 
  183.                     Configuration
  184. =========================================================*/
  185.  
  186. // Load configuration from a file.
  187. // Returns TRUE on success, FALSE on failure
  188. BOOL FAR PASCAL CT_LoadConfiguration (LPSTR lpszFile)
  189. {
  190. #ifdef _BRAVADO
  191.     return (VW_LoadConfiguration (lpszFile));
  192. #endif
  193.  
  194. #ifdef _VBLASTER
  195.     return vbcLoadConfiguration ();     // Does not support file name!!!
  196. #endif
  197. }
  198.  
  199. // Save configuration to a file.
  200. // Returns TRUE on success, FALSE on failure
  201. BOOL FAR PASCAL CT_SaveConfiguration (LPSTR lpszFile)
  202. {
  203. #ifdef _BRAVADO
  204.     return (VW_SaveConfiguration (lpszFile));
  205. #endif
  206.  
  207. #ifdef _VBLASTER
  208.     return vbcSaveConfiguration ();     // Does not support file name!!!
  209. #endif
  210. }
  211.  
  212. // Set the video source
  213. // nSource ranges from 0 to ...
  214. void FAR PASCAL CT_SetVideoSource (int nSource)
  215. {
  216. #ifdef _BRAVADO
  217.     VW_SetVidSource (nSource);
  218. #endif
  219.  
  220. #ifdef _VBLASTER
  221.     vbcSetVideoSource ((WORD) nSource);
  222. #endif
  223. }
  224.  
  225. // Get the number of video input channels available.
  226. int FAR PASCAL CT_GetVideoChannelCount (void)
  227. {
  228. #ifdef _BRAVADO
  229.     return 3;   // Some cables only have 1 input, but always allow 3
  230. #endif
  231.  
  232. #ifdef _VBLASTER
  233.     return 3;
  234. #endif
  235. }
  236.  
  237. // Set the video standard
  238. // 0 = NTSC, 1 = PAL
  239. void FAR PASCAL CT_SetVideoStandard (int nStandard)
  240. {
  241. #ifdef _BRAVADO
  242.     VW_SetVidStandard (nStandard == 0 ? 1 : 0);
  243. #endif
  244.  
  245. #ifdef _VBLASTER
  246.    vbcSetInputFormat (nStandard == 0 ? CF_NTSC : CF_PAL);
  247. #endif
  248. }
  249.  
  250. // Return TRUE if the device can accept SVideo
  251. BOOL FAR PASCAL CT_HasSVideo ()
  252. {
  253. #ifdef _BRAVADO
  254.     return TRUE;
  255. #endif
  256.  
  257. #ifdef _VBLASTER
  258.    return FALSE;
  259. #endif
  260. }
  261.  
  262. // Set the selected input channel format to:
  263. // 0 = composite
  264. // 1 = SVideo
  265. // 2 = RGB (someday?)
  266.  
  267. BOOL FAR PASCAL CT_SetVideoCableFormat (int nInputMode)
  268. {
  269. #ifdef _BRAVADO
  270.     VW_SetSVid (nInputMode);
  271.     return TRUE;
  272. #endif
  273.  
  274. #ifdef _VBLASTER
  275.     return FALSE;       // Can't do SVideo
  276. #endif
  277. }
  278.  
  279. // Set the Color control registers 
  280. // nVal on input ranges from 0 to 0x3f
  281. void FAR PASCAL CT_SetColor(int nReg, int nVal)
  282. {
  283. #ifdef _BRAVADO
  284.     // All Bravado values EXCEPT hue range 0-0x3f, hue goes from 0-0xff
  285.     if (nReg == 0)
  286.         nVal *= 4;      
  287.     VW_SetColor (nReg, nVal);
  288. #endif
  289.  
  290. #ifdef _VBLASTER
  291.     // All Video Blaster color values range 0-0xff
  292.     nVal *= 4; 
  293.     switch (nReg) {
  294.         case CT_COLOR_HUE:          nReg = 3; break;
  295.         case CT_COLOR_BRIGHTNESS:   nReg = 0; break;
  296.         case CT_COLOR_SAT:          nReg = 1; break;
  297.         case CT_COLOR_CONTRAST:     nReg = 2; break;
  298.     }
  299.     vbcSetColor (nReg, (BYTE) nVal);
  300. #endif
  301. }
  302.  
  303.  
  304. /*======================================================== 
  305.                     Rectangles
  306. =========================================================*/
  307.  
  308. // Create and Position the overlay window
  309. void FAR PASCAL CT_SetDisplayRect (LPRECT lpRectangle)
  310. {
  311.     RECT rR = *lpRectangle;
  312.  
  313.     OffsetRect (&rR, rcLastScreen.left, rcLastScreen.top);
  314.  
  315. #ifdef _BRAVADO
  316.     VW_SetVidWindow (rR.left, rR.top, WidthRect(rR), HeightRect(rR), 1);
  317. #endif
  318.  
  319. #ifdef _VBLASTER
  320.     vbcCreateWindow (rR.left, rR.top, WidthRect(rR), HeightRect(rR), 1);
  321. #endif
  322. }
  323.  
  324. void FAR PASCAL CT_SetPanAndScroll (LPRECT lpRectangle)
  325. {
  326.     RECT rR = *lpRectangle;
  327. #ifdef _BRAVADO
  328.     VW_SetVidPan (rR.left, rR.top);
  329. #endif
  330.  
  331. #ifdef _VBLASTER
  332.     vbcPanWindow (rR.left, rR.top);
  333. #endif
  334.         
  335. }
  336.  
  337. /*======================================================== 
  338.             Overlay keying and Painting
  339. =========================================================*/
  340.  
  341. // Set the overlay key color
  342. // Returns a brush which is used to paint the key color
  343. HBRUSH FAR PASCAL CT_SetKeyColor ()
  344. {
  345. #ifdef _BRAVADO
  346.     {
  347.         HWND hWnd;
  348.         HDC  hDC;
  349.         int  iColors;
  350.  
  351.         hWnd = GetDesktopWindow ();
  352.         hDC  = GetDC (hWnd);
  353.         iColors = GetDeviceCaps (hDC, NUMCOLORS);
  354.         ReleaseDC (hWnd, hDC);
  355.  
  356.         // Bravado16 only uses high byte for key, so create a special brush
  357.         if (iColors > 256) {
  358.             COLORREF cref = RGB (0x7f, 0, 0x7f);
  359.  
  360.             VW_SetRGBKeyColor (cref);
  361.             return  (CreateSolidBrush (cref));
  362.         }
  363.         else {
  364.             VW_SetKeyColor (KEY_COLOR_INDEX);
  365.             return  (CreateSolidBrush (PALETTEINDEX (KEY_COLOR_INDEX)));
  366.         }
  367.         hDC  = GetDC (hWnd);
  368.     }
  369. #endif
  370.  
  371. #ifdef _VBLASTER
  372.     vbcSetColorKey ((WORD) KEY_COLOR_INDEX);
  373.     return  (CreateSolidBrush (PALETTEINDEX (KEY_COLOR_INDEX)));
  374. #endif
  375. }
  376.  
  377. // Turn overlay display on or off
  378. void FAR PASCAL CT_OverlayEnable (BOOL fDisplay)
  379. {
  380.     fOverlayEnabled = fDisplay;
  381.  
  382. #ifdef _BRAVADO
  383.     VW_SetVidShow (fDisplay);
  384. #endif
  385.  
  386. #ifdef _VBLASTER
  387.     if (fDisplay)
  388.         vbcEnableVideo ();
  389.     else
  390.         vbcDisableVideo ();
  391. #endif
  392. }
  393.  
  394.  
  395. // Update the overlay window rectangle and paint the key color
  396. void FAR PASCAL CT_Update (HWND hWnd, HDC hDC)
  397. {
  398.     RECT rcScreen, rcClient;
  399.     HBRUSH hbrOld;
  400.  
  401.     rcScreen = grcDestExtOut;
  402.     rcScreen.right = rcScreen.left + gwWidth -1;
  403.     rcScreen.bottom = rcScreen.top + gwHeight -1;
  404.  
  405. #ifdef _BRAVADO
  406.     if (!EqualRect (&rcScreen, &rcLastScreen)) {
  407.         VW_SetVidWindow (rcScreen.left, rcScreen.top, 
  408.                 WidthRect(rcScreen), HeightRect(rcScreen), 1);
  409.     }
  410. #endif
  411.  
  412. #ifdef _VBLASTER
  413.     if (!EqualRect (&rcScreen, &rcLastScreen)) {
  414.         vbcSetWindowPosition (rcScreen.left, rcScreen.top);
  415.         vbcSetWindowSize (WidthRect(rcScreen), HeightRect(rcScreen), 1);
  416.     }
  417. #endif
  418.  
  419.     CT_SetPanAndScroll (&grcSourceExtOut);
  420.  
  421.     // Paint the key color into grcDestExtOut (which is in screen coords)
  422.     rcClient = grcDestExtOut;
  423.     ScreenToClient (hWnd, (LPPOINT) &rcClient);
  424.     ScreenToClient (hWnd, (LPPOINT) &rcClient+1);
  425.     hbrOld = SelectObject (hDC, hOverlayBrush);
  426.     PatBlt (hDC, rcClient.left, rcClient.top, 
  427.             rcClient.right - rcClient.left, 
  428.             rcClient.bottom - rcClient.top, 
  429.             PATCOPY);
  430.     SelectObject (hDC, hbrOld);
  431.  
  432.     rcLastScreen = rcScreen;
  433. }
  434.  
  435. /*======================================================== 
  436.             Image acquistion and grabbing
  437. =========================================================*/
  438.  
  439. // Turn acquisition of images into frame buffer on or off
  440. // Not interrupt callable, since it enters the client DLL.
  441. void FAR PASCAL CT_Acquire (BOOL fAcquire)
  442. {
  443. #ifdef _BRAVADO
  444.     VW_SetFreezeVid (fAcquire ? 0 : 1); // Backwards
  445. #endif
  446.  
  447. #ifdef _VBLASTER
  448.     if (fAcquire)
  449.         vbcUnFreezeVideo ();
  450.     else
  451.         vbcFreezeVideo ();
  452. #endif
  453.     
  454. }
  455.  
  456. // This routine is interrupt callable, and bypasses
  457. // the client DLL.
  458. void FAR PASCAL CT_PrivateAcquire (BOOL fAcquire)
  459. {
  460.     CT_WritePCVideo (0x20, ((CT_ReadPCVideo (0x20) & 0xfe) 
  461.         | (fAcquire ? 1 : 0)));
  462.  
  463.     // On a FREEZE, wait for acquisition to complete
  464.     // otherwise PCVIDEO asserts the READY line for 20mS.
  465.     // when the first video memory read occurs!!!
  466.     // This behavior violates PC bus specs.
  467.     if (!fAcquire)
  468.         while (CT_ReadPCVideo (0x20) & 1);
  469. }
  470.  
  471.  
  472. // Capture a single frame
  473. // Return frozen
  474. void FAR PASCAL CT_GrabFrame (void)
  475. {
  476.     CT_Acquire (TRUE);
  477.     CT_WaitVSync (0);    // Wait Even
  478.     CT_WaitVSync (1);    // Wait Odd
  479.     CT_Acquire (FALSE);
  480. }
  481. /*======================================================== 
  482.               Interrupts and Sync
  483. =========================================================*/
  484. // Set the IRQ used by the device.
  485. // Returns the IRQ actually set.
  486. int FAR PASCAL CT_SetIRQUsed (int nIRQ)
  487. {
  488.  
  489. #ifdef _BRAVADO
  490.     return 9;          // only 9 is available from this card
  491. #endif
  492.  
  493. #ifdef _VBLASTER
  494.     {
  495.         int nTemp;
  496.         switch (nIRQ) {
  497.            case 5:  nTemp = 1; break;
  498.            case 10: nTemp = 2; break;
  499.            case 11: nTemp = 4; break;
  500.            case 12: nTemp = 8; break;
  501.            default: return (CT_GetIRQUsed ()); // illegal value, return default
  502.         }
  503.         CT_WritePCVideo (0x82, nTemp);
  504.         return nIRQ;
  505.     }
  506. #endif
  507. }
  508.  
  509. // Returns the IRQ used by the device
  510. int FAR PASCAL CT_GetIRQUsed ()
  511. {
  512. #ifdef _BRAVADO
  513.     return 9;          // only 9 is available from this card
  514. #endif
  515.  
  516. #ifdef _VBLASTER
  517.     return vbcGetIntrNo();
  518. #endif
  519. }
  520.  
  521. #define EVEN_VSYNC_INTERRUPT 0x01
  522. #define  ODD_VSYNC_INTERRUPT 0x02
  523.  
  524. // Enable the PCVideo chip to create odd and even interrupts
  525. void FAR PASCAL CT_IRQEnable (void)
  526. {
  527. #if FRAME_INTERRUPT
  528.     CT_WritePCVideo (0x09, EVEN_VSYNC_INTERRUPT);
  529. #else
  530.     CT_WritePCVideo (0x09, EVEN_VSYNC_INTERRUPT | ODD_VSYNC_INTERRUPT);
  531. #endif
  532. }
  533.  
  534. void FAR PASCAL CT_IRQDisable (void)
  535. {
  536.     CT_WritePCVideo (0x09, 0);         // Disable Interrupts
  537. }
  538.  
  539. // Clear PCVideo chip interrupts
  540. void FAR PASCAL CT_IRQClear (void)
  541. {
  542.     CT_WritePCVideo (0x09, 0);         // Clear the interrupt
  543.  
  544. #if FRAME_INTERRUPT
  545.     CT_WritePCVideo (0x09, EVEN_VSYNC_INTERRUPT);  // Re-enable it
  546. #else
  547.     CT_WritePCVideo (0x09, ODD_VSYNC_INTERRUPT | EVEN_VSYNC_INTERRUPT);  // Re-enable it
  548. #endif
  549. }
  550.  
  551.  
  552. // Wait for Vertical Sync
  553. // nSync = 0, wait even
  554. // nSync = 1, wait odd
  555. // nSync = 2, wait either
  556. void FAR PASCAL CT_WaitVSync (int nSync)
  557. {
  558.     WORD  wRegVal;
  559.     BOOL  bOdd;
  560.     DWORD dwStartTime = timeGetTime();
  561.     
  562.     while (timeGetTime () - dwStartTime < 33) {
  563.         wRegVal = CT_ReadPCVideo (9);
  564.         bOdd = wRegVal & 0x08;
  565.         if (wRegVal & 0x04) {        // if VSync
  566.            if ((nSync == 2) || 
  567.               ((nSync == 1) && bOdd) ||
  568.               ((nSync == 0) && !bOdd))
  569.               break;
  570.         }
  571.     }
  572. }
  573.